using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Web.Mvc;
using System.Web.Profile;
using System.Web.Routing;
using System.Web.Security;
using Core.BOL;
using Core.DAL;
using Core.Extentions;
using Core.Utils;
using System.Security.Permissions;

namespace ScoutNET.Controllers
{
    public class MembresController : ApplicationController
    {
        private SectionRepository sr = new SectionRepository();
        private ImagesRepository ir = new ImagesRepository();
        private UsersRepository ur = new UsersRepository();
        private FunctionRepository fr = new FunctionRepository();
        private MailToGenerateRepository mtgr = new MailToGenerateRepository();

        #region Views
        //
        // GET: /Membres/Index
        public ActionResult Index(int? page)
        {
            // Meta Tag
            ViewData["PageTitle"] = Resources.Page_Membres_Title;
            ViewData["PageDescription"] = Resources.Page_Membres_Description;

            //Breadcrumb
            string[] saBreadcrumb = new String[2];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = Resources.Pages_Members_Breadcrumb;
            ViewData["Breadcrumb"] = saBreadcrumb;

            ViewData["UserType"] = UsersRepository.GetUserType();

            List<tSite_Section> lSections = sr.GetSections();
            int itemPage = 40;
            int totalUser;
            int pageID = (page == null || page == 0) ? 0 : (int)page - 1;
            MembershipUserCollection muc = Membership.GetAllUsers(pageID, itemPage, out totalUser);
            double totalItems = Convert.ToDouble(totalUser);
            int totalPages = (int)Math.Ceiling(totalItems / itemPage);
            int i = (pageID != 0) ? (pageID * itemPage) + 1 : 1;

            if (muc != null && muc.Count > 0)
            {
                using (DataTable dtUsers = new DataTable())
                {
                    dtUsers.Columns.Add("UserNumItem");
                    dtUsers.Columns.Add("UserID");
                    dtUsers.Columns.Add("UserName");
                    dtUsers.Columns.Add("CreationDate");
                    dtUsers.Columns.Add("Totem");
                    dtUsers.Columns.Add("Section");
                    dtUsers.Columns.Add("Role");
                    dtUsers.Columns.Add("WebSite");
                
                    foreach (MembershipUser user in muc)
                    {
                        ProfileBase pb = ProfileBase.Create(user.UserName);
                        string[] roles = Roles.GetRolesForUser(user.UserName);
                        if (pb != null)
                        {
                            string sectionName = string.Empty;
                            tSite_Section userSection = lSections.Where(p => p.ID == (int)pb["SectionID"]).SingleOrDefault();
                            if (userSection != null)
                            {
                                sectionName = userSection.Section;
                            }

                            DataRow row = dtUsers.NewRow();
                            row["UserNumItem"] = i++;
                            row["UserID"] = (Guid)user.ProviderUserKey;
                            row["UserName"] = user.UserName;
                            row["CreationDate"] = user.CreationDate.ToString("dd/MM/yyyy");
                            row["Totem"] = pb["Totem"];
                            row["WebSite"] = pb["WebSite"];
                            row["Section"] = sectionName;
                            row["Role"] = roles[0];
                            dtUsers.Rows.Add(row);
                        }
                    }

                    ViewData["TotalPages"] = totalPages;
                    ViewData["Page"] = pageID + 1;
                    ViewData["dtUsers"] = dtUsers;
               
                }
                return View();
            }
            else
            {
                ViewData["ErrorMessage"] = Resources.Page_Membres_NoItem;
                return View("Error");
            }
        }

        //
        // GET: /Membres/Details/00000000-0000-0000-0000-000000000000/UserName
        public ActionResult Details(Guid ID)
        {
            MembershipUser mu = Membership.GetUser(ID);
            
            if (mu != null)
            {
                ProfileBase pb = ProfileBase.Create(mu.UserName);
                string[] roles = Roles.GetRolesForUser(mu.UserName);

                List<sp_Site_GetRandomUserImageResult> lImages = ir.GetRandomUserImage(4, ID);

                ViewData["PageTitle"] = Resources.Profil_Detail_Title.Replace("[USERNAME]", mu.UserName.UppercaseFirst());
                ViewData["PageDescription"] = Resources.Profil_Detail_Description.Replace("[USERNAME]", mu.UserName.UppercaseFirst());

                string[] saBreadcrumb = new String[3];
                saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
                saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Pages_Members_Breadcrumb, "Default", "Index", "Membres", null, null);
                saBreadcrumb[2] = Resources.Profil_Detail_Breadcrumb.Replace("[USERNAME]", mu.UserName.UppercaseFirst());
                ViewData["Breadcrumb"] = saBreadcrumb;

                ViewData["Role"] = (roles.Count() > 0) ? roles[0] : string.Empty;
                ViewData["UserSection"] = (!string.IsNullOrEmpty(pb["SectionID"].ToString()) && pb["SectionID"].ToString() != "0") ? sr.GetSectionsById((int)pb["SectionID"]).Section : string.Empty;
                ViewData["User"] = mu;
                ViewData["UserImages"] = lImages;
                ViewData["NoPicture"] = Resources.Membres_Detail_NoPicture.Replace("[USERNAME]", mu.UserName);

                return View("Detail", pb);
            }    
            
            return View("Error404");
        }

        //
        // GET: /Membres/Manage
        [Authorize(Roles = "C.U")]
        public ActionResult Manage()
        {
            ViewData["PageTitle"] = Resources.Membres_Manage_Title;
            ViewData["PageDescription"] = Resources.Membres_Manage_Description;

            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Pages_Members_Breadcrumb, "Default", "Index", "Membres", null, null);
            saBreadcrumb[2] = Resources.Membres_Manage_Breadcrumb;
            ViewData["Breadcrumb"] = saBreadcrumb;

            List<aspnet_User> lUsers = ur.GetNotApprouvedUser().Where(p => p.Role == "Animateur" || p.Role == "C.U").ToList();
            ViewData["NotApprouvedUsers"] = lUsers;

            List<tSite_Section> lSection = sr.GetNonAdministrativeSections();
            ViewData["SlSection"] = new SelectList(lSection, "ID", "Section");
            ViewData["SlFunctions"] = new SelectList(fr.GetAllFunctions(), "RoleId", "RoleName");

            return View();
        }

        //
        // POST: /Membres/Manage
        [HttpPost]
        [Authorize(Roles = "C.U")]
        public EmptyResult ValidateAdminUser(FormCollection fc)
        {
            Guid userID = new Guid(fc["UID"]);
            MembershipUser mu = Membership.GetUser(userID);

            if (mu != null)
            {
                string siteName = ConfigurationManager.AppSettings["SiteName"];
                string siteUrl = ConfigurationManager.AppSettings["SiteUrl"];
                Uri uSiteUrl = new Uri(siteUrl);
                tSite_Section s = sr.GetSectionsById(8);
                string mailUrl = siteUrl + Url.Action("MembersAdminValidation", new { controller = "Mail", id = userID });

                mu.IsApproved = true;
                Membership.UpdateUser(mu);
                
                string mailSubject = string.Empty;
                string mailBody = Mail.GetMailHTML(mailUrl, out mailSubject);
                mailBody = mailBody.AddUrlInHref(uSiteUrl).AddUrlInSrc(uSiteUrl);
                Mail.SendMail(mu.Email, mailSubject, mailBody, s.Email, s.Section.UppercaseFirst() + " - " + siteName.UppercaseFirst());
            }

            return new EmptyResult();
        }

        //
        // GET : /Membres/Edit/00000000-0000-0000-0000-000000000000
        [Authorize(Roles = "C.U")]
        public ActionResult Edit(Guid ID)
        {
            List<tSite_Section> lUserSection = sr.GetUserSectionsByUserId(ID);
            List<tSite_Section> lSections = sr.GetNonAdministrativeSections();

            MembershipUser mu = Membership.GetUser(ID);
            ProfileBase pb = ProfileBase.Create(mu.UserName);
            string roles = Roles.GetRolesForUser(mu.UserName)[0];

            ViewData["MembershipUser"] = mu;
            ViewData["ProfileBase"] = pb;
            ViewData["UserSections"] = lUserSection;
            ViewData["Sections"] = lSections;
            ViewData["SlSection"] = new SelectList(lSections, "ID", "Section", pb["SectionID"].ToString());
            ViewData["SlFunctions"] = new SelectList(fr.GetAllFunctions(), "RoleName", "RoleName", roles);

            return View();
        }

        //
        // POST : /Membres/Edit/00000000-0000-0000-0000-000000000000
        [HttpPost]
        [Authorize(Roles = "C.U")]
        public ActionResult Edit(FormCollection fc, Guid ID)
        {
            if (!ValidateUser(fc))
            {
                List<tSite_Section> lUserSection = sr.GetUserSectionsByUserId(ID);
                List<tSite_Section> lSections = sr.GetNonAdministrativeSections();

                MembershipUser mu = Membership.GetUser(ID);
                ProfileBase pb = ProfileBase.Create(mu.UserName);
                string role = Roles.GetRolesForUser(mu.UserName)[0];

                ViewData["MembershipUser"] = mu;
                ViewData["UserSections"] = lUserSection;
                ViewData["Sections"] = lSections;
                ViewData["SlSection"] = new SelectList(lSections, "ID", "Section", pb["SectionID"].ToString());
                ViewData["SlFunctions"] = new SelectList(fr.GetAllFunctions(), "RoleName", "RoleName", role);

                return View();
            }
            else
            {
                MembershipUser mu = Membership.GetUser(ID);
                string role = Roles.GetRolesForUser(mu.UserName)[0];

                //Update Sections
                string[] infoSection = fc["infoSection"].Split(',');
                List<int> sectionIDs = new List<int>();
                foreach (string sectionID in infoSection) sectionIDs.Add(Convert.ToInt32(sectionID));

                aspnet_User u = ur.GetUserById(ID);
                u.SectionIDs = sectionIDs;
                ur.UpdateSectionsByUserId(u);
                ur.Save();

                //Update Roles
                if (!Roles.IsUserInRole(mu.UserName, fc["SlFunctions"]))
                {
                    string[] userRoles = Roles.GetRolesForUser(mu.UserName);
                    Roles.RemoveUserFromRoles(mu.UserName, userRoles);
                    Roles.AddUserToRole(mu.UserName, fc["SlFunctions"]);
                }

                //Update Section
                ProfileBase pb = ProfileBase.Create(mu.UserName);
                pb["SectionID"] = int.Parse(fc["SlSection"]);
                pb.Save();

                ViewData["ValidationMessage"] = "Merci";
            }

            return View("Validation");
        }

        //
        // GET : /Membres/Delete/00000000-0000-0000-0000-000000000000
        [Authorize(Roles = "C.U")]
        public ActionResult Delete(Guid ID)
        {
            ViewData["ID"] = ID;

            return View();
        }

        //
        // POST : /Membres/Delete/00000000-0000-0000-0000-000000000000
        [HttpPost]
        [Authorize(Roles = "C.U")]
        public EmptyResult Delete(FormCollection fc)
        {
            MembershipUser mu = Membership.GetUser(new Guid(fc["ID"]));
            if (mu != null)
            {
                Membership.DeleteUser(mu.UserName, true);
            }

            tMail_ToGenerate tg = new tMail_ToGenerate();
            tg.Action = "MembresAdminDelete";
            tg.ItemID = null;
            tg.SID = 8;
            tg.InsertDate = DateTime.Now.GetNowTimeByTimeZone();
            mtgr.InsertMail(tg);
            mtgr.Save();

            return new EmptyResult();
        }

        //
        // GET: /Membres/Users
        [Authorize(Roles = "C.U")]
        public JsonResult UsersList(string q)
        {
            List<aspnet_User> lAspUsers = ur.SearchUsers(q);
            
            MembershipUser anonymeUser = Membership.GetUser(ConfigurationManager.AppSettings["AnonymeUser"]);
            MembershipUser currentUser = Membership.GetUser();

            var users = (from u in lAspUsers
                         select new
                         {
                             u.UserId,
                             u.UserName,
                             u.tSite_UserProfile.FirstName,
                             u.tSite_UserProfile.LastName
                         });

            if (anonymeUser != null && currentUser != null)
            {
                users = users.Where(p => p.UserName != anonymeUser.UserName && p.UserName != currentUser.UserName);
            }

            var lUsers = users.Select((item, index) => new
            {
                Item = item,
                Index = index + 1
            });

            return this.Json(lUsers.ToList(), JsonRequestBehavior.AllowGet);
        }

        //
        // GET: /Membres/Users
        [Authorize(Roles = "C.U")]
        public JsonResult AdvancedUsersList(string sectionIds, string functionIds)
        {
            List<aspnet_User> lUser = ur.GetUsersBySectionsAndFunction(sectionIds, functionIds);

            MembershipUser anonymeUser = Membership.GetUser(ConfigurationManager.AppSettings["AnonymeUser"]);
            MembershipUser currentUser = Membership.GetUser();

            var users = (from u in lUser
                         select new
                         {
                             UserID = u.UserId,
                             UserName = u.UserName.UppercaseFirst(),
                             FirstName = u.tSite_UserProfile.FirstName.UppercaseFirst(),
                             LastName = u.tSite_UserProfile.LastName.UppercaseFirst(),
                             Email = u.Email.ToLower(),
                             IsLocked = u.aspnet_Membership.IsLockedOut,
                             IsApprouved = u.aspnet_Membership.IsApproved,
                             Section = u.SectionName
                         });

            if (anonymeUser != null && currentUser != null)
            {
                users = users.Where(p => p.UserName != anonymeUser.UserName && p.UserName != currentUser.UserName);
            }

            var lUsers = users.Select((item, index) => new
            {
                Item = item,
                Index = index + 1
            });

            return this.Json(lUsers.ToList(), JsonRequestBehavior.AllowGet);
        }

        //
        // GET: /Membres/GetUser
        [Authorize(Roles = "C.U")]
        public JsonResult GetUser(string uid)
        {
            Guid userId = new Guid(uid);

            aspnet_User user = ur.GetUserById(userId);
            aspnet_User[] aUser = new aspnet_User[1];
            aUser[0] = user;

            var users = (from u in aUser
                         select new
                         {
                             UserID = u.UserId,
                             UserName = u.UserName.UppercaseFirst(),
                             FirstName = u.tSite_UserProfile.FirstName.UppercaseFirst(),
                             LastName = u.tSite_UserProfile.LastName.UppercaseFirst(),
                             Email = u.Email.ToLower(),
                         }).ToList();

            var lUsers = users.Select((item, index) => new
            {
                Item = item,
                Index = index + 1
            });
                
            return this.Json(lUsers.SingleOrDefault(), JsonRequestBehavior.AllowGet);
        }

        //
        // GET: /Membres/ImageResize/ID/Title
        [OutputCache(CacheProfile="Photo")]
        [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
        public FileResult ImageResize(int ID, string title)
        {
            tSite_Photos_Image img = ir.GetImageByID(ID);
            Dictionary<string, int> imageSize = Imaging.GetImageSize(ImageMode.Members);
            string picturePath = ConfigurationManager.AppSettings["GalleryPath"] + img.AID.ToString("D6") + "/" + img.ImageName.ToString() + ".jpg";

            string filePath = Server.MapPath(picturePath);
            byte[] baImage = Files.FileToArray(filePath);
            Image i = Imaging.FromByteArray(baImage);

            baImage = Imaging.GetResizedImage((int)ID, ImageMode.Members, (i.Height > i.Width), false);

            return new FileContentResult(baImage, "image/jpeg");
        }
        #endregion

        #region Private Methode
        private bool ValidateUser(FormCollection fc)
        {
            ModelState.SetModelValue("title", ValueProvider.GetValue("title"));
            ModelState.SetModelValue("text", ValueProvider.GetValue("text"));

            if (String.IsNullOrEmpty(fc["title"]))
            {
                ModelState.AddModelError("title", Resources.News_Create_Error_Title);
            }
            if (String.IsNullOrEmpty(fc["text"]))
            {
                ModelState.AddModelError("text", Resources.News_Create_Error_Texte);
            }
            //return ModelState.IsValid;
            return true;
        }
        #endregion
    }
}
